package suncertify.ps;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import suncertify.bs.BusinessService;
import suncertify.bs.BusinessServiceImpl;
import suncertify.bs.RemoteBusinessService;
import suncertify.dao.EnumSearchCriteria;
import suncertify.dao.RoomRecord;
import suncertify.db.exc.RecordNotFoundException;
import suncertify.db.exc.SecurityException;

public class BookingView extends JFrame {

    private String path;
    private String ip;
    private String port;
    private ApplicationRunMode mode;
    private BusinessService service;

    private final int iw = 4;
    private final Insets formPanelInsets = new Insets(iw, iw, iw, iw);

    private JButton jbtSearch;
    private JButton jbtBook;
    private JButton jbtRefresh;

    private JLabel jlbName;
    private JLabel jlbLocation;
    private JTextField jtxtName;
    private JTextField jtxtLocation;

    private JPanel panelSearchCriteria;
    private JPanel panelTable;
    private JPanel panelButtons;

    private JTable table;
    private BookingTableModel tm;

    /**
     * Constructor to start the booking view when server is running (Network
     * mode).
     * 
     * @param path
     * @param ip
     * @param port
     * @param mode
     */
    public BookingView(String path, String ip, String port,
	    ApplicationRunMode mode) {
	
	this.path = path;
	this.ip = ip;
	this.port = port;
	this.mode = mode;
	createAndShowGUI();
    }

    /**
     * Constructor to start the booking view when server is NOT running
     * (Standalone mode).
     * 
     * @param path
     * @param server
     */
    public BookingView(String path, ApplicationRunMode mode) {
	this.path = path;
	this.mode = mode;
	createAndShowGUI();
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    public void createAndShowGUI() {

	Border etchedBorder = new EtchedBorder();
	Border emptyBorder = new EmptyBorder(9, 9, 9, 9);
	Border panelBorder = BorderFactory.createCompoundBorder(emptyBorder,
		etchedBorder);

	GridBagConstraints gbc = new GridBagConstraints();
	gbc.insets = formPanelInsets;
	gbc.fill = GridBagConstraints.BOTH;

	// Start Panel for Search Criterias
	panelSearchCriteria = new JPanel();
	panelSearchCriteria.setLayout(new GridBagLayout());
	panelSearchCriteria.setBorder(panelBorder);

	// Hotel Name
	jlbName = new JLabel("Hotel Name: ");
	gbc.gridx = 0;
	gbc.gridy = 0;
	panelSearchCriteria.add(jlbName, gbc);

	jtxtName = new JTextField();
	jtxtName.setColumns(15);
	gbc.gridx = 1;
	gbc.gridy = 0;
	panelSearchCriteria.add(jtxtName, gbc);

	// Hotel Location
	jlbLocation = new JLabel("Hotel Location: ");
	gbc.gridx = 0;
	gbc.gridy = 1;
	panelSearchCriteria.add(jlbLocation, gbc);

	jtxtLocation = new JTextField();
	jtxtLocation.setColumns(15);
	gbc.gridx = 1;
	gbc.gridy = 1;
	panelSearchCriteria.add(jtxtLocation, gbc);

	jbtSearch = new JButton("Search");
	jbtSearch.addActionListener(search);
	gbc.gridx = 2;
	gbc.gridy = 1;
	panelSearchCriteria.add(jbtSearch, gbc);

	// Start Table
	panelTable = new JPanel();

	if (ApplicationRunMode.NETWORK_CLIENT.equals(mode)) {
	    try {
		Registry registry = LocateRegistry.getRegistry(ip,
			Integer.parseInt(port));
		// String url = "rmi://" + ip + ":" + port + "/BusinessService";

		service = (RemoteBusinessService) registry
			.lookup("RemoteBusinessService");

		// String url = "rmi://192.168.178.24:1099/BusinessService";
		// service = (BusinessService) registry
		// .lookup("BusinessService");
		// service = (BusinessService) registry.lookup(url);
		// service = (BusinessService) Naming.lookup(url);
	    } catch (RemoteException re) {
		// TODO
	    } catch (NotBoundException re) {
		// TODO
	    }
	} else if (ApplicationRunMode.STANDALONE_CLIENT.equals(mode)) {
	    try {
		service = new BusinessServiceImpl(path);
	    } catch (RecordNotFoundException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    } catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    }
	}
	List<RoomRecord> data = new ArrayList<RoomRecord>();
	List<String> column = new ArrayList<String>();
	column.add("Hotel Name");
	column.add("Hotel Location");
	column.add("Size");
	column.add("Smoking");
	column.add("Rate");
	column.add("Date");
	column.add("Customer Id");

	try {
	    data = service.searchRoom(null);
	} catch (RecordNotFoundException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	tm = new BookingTableModel(data, column);
	table = new JTable(tm);
	table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	ListSelectionModel listSelectionModel = table.getSelectionModel();
	listSelectionModel
		.addListSelectionListener(new ListSelectionListener() {

		    @Override
		    public void valueChanged(ListSelectionEvent e) {
			jbtBook.setEnabled(true);

		    }
		});
	table.setSelectionModel(listSelectionModel);
	panelTable.add(new JScrollPane(table));

	// Buttons
	panelButtons = new JPanel();
	panelButtons.setLayout(new GridBagLayout());

	jbtRefresh = new JButton("Refresh");
	jbtRefresh.addActionListener(refresh);
	gbc.gridx = 0;
	gbc.gridy = 1;
	panelButtons.add(jbtRefresh, gbc);

	jbtBook = new JButton("Book Now");
	jbtBook.addActionListener(book);
	jbtBook.setEnabled(false);
	gbc.gridx = 2;
	gbc.gridy = 1;
	panelButtons.add(jbtBook, gbc);

	add(panelSearchCriteria, BorderLayout.NORTH);
	add(panelTable, BorderLayout.CENTER);
	add(panelButtons, BorderLayout.SOUTH);

	init();
    }

    private void init() {

	this.setTitle("Urly Bird");
	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	this.pack();
	this.setSize(500, 650);

	// Center
	Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
	int x = (int) ((d.getWidth() - this.getWidth()) / 2);
	int y = (int) ((d.getHeight() - this.getHeight()) / 2);
	this.setLocation(x, y);
	this.setResizable(false);
	this.setVisible(true);
    }

    ActionListener book = new ActionListener() {
	public void actionPerformed(ActionEvent e) {
	    int selectedRow = table.getSelectedRow();
	    RoomRecord room = tm.getRoomAtSelectedRow(selectedRow);
	    String showInputDialog = JOptionPane
		    .showInputDialog("Please enter your Customer Id");
	    room.setOwner(showInputDialog);

	    try {
		service.bookRoom(room.getId(), room);
		// Inform tablemodel about change
		tm.fireTableDataChanged();
	    } catch (RecordNotFoundException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    } catch (SecurityException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    } catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	    }
	}
    };

    ActionListener search = new ActionListener() {
	public void actionPerformed(ActionEvent e) {

	    try {
		Map<EnumSearchCriteria, String> searchCriterias = new HashMap<EnumSearchCriteria, String>();

		searchCriterias
			.put(EnumSearchCriteria.NAME, jtxtName.getText());
		searchCriterias.put(EnumSearchCriteria.LOCATION,
			jtxtLocation.getText());

		List<RoomRecord> roomList = service.searchRoom(searchCriterias);
		tm.roomList = roomList;
		tm.fireTableDataChanged();

	    } catch (RecordNotFoundException ex) {
		// TODO Auto-generated catch block
		ex.printStackTrace();
	    } catch (IOException exc) {
		// TODO Auto-generated catch block
		exc.printStackTrace();
	    }
	}
    };

    ActionListener refresh = new ActionListener() {
	public void actionPerformed(ActionEvent e) {

	    try {
		List<RoomRecord> roomList = service.searchRoom(null);
		tm.roomList = roomList;
		tm.fireTableDataChanged();

	    } catch (RecordNotFoundException ex) {
		// TODO Auto-generated catch block
		ex.printStackTrace();
	    } catch (IOException exc) {
		// TODO Auto-generated catch block
		exc.printStackTrace();
	    }
	}
    };

    public static void main(final String[] args) {
	// BookingView view = new BookingView(
	// "D:\\Entwicklung\\SCJD\\Certification\\Aufgabe\\File\\db-1x1.db",
	// ApplicationRunMode.STANDALONE_CLIENT);
	// view.createAndShowGUI();
    }
}
